package com.vanke.devops.domain.domain.endpoints.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.dockerjava.api.model.Info;
import com.vanke.core.util.StringUtil;
import com.vanke.devops.dal.dao.EndpointsMapper;
import com.vanke.devops.dal.model.Endpoints;
import com.vanke.devops.dal.util.collection.CollectionUtils;
import com.vanke.devops.domain.DomainConstants;
import com.vanke.devops.domain.base.BaseServiceImpl;
import com.vanke.devops.domain.domain.endpoints.EndpointsWebSocket;
import com.vanke.devops.domain.domain.endpoints.IEndpointsService;
import com.vanke.devops.domain.domain.endpoints.dto.EndpointsDTO;
import com.vanke.devops.domain.enums.EndpointsErrorCode;
import com.vanke.devops.domain.manager.aliyun.AliyunMonitorManager;
import com.vanke.devops.domain.manager.aliyun.bean.Node;
import com.vanke.devops.domain.manager.docker.DockerManager;
import com.vanke.devops.domain.manager.influxdb.InfluxDbManager;
import com.vanke.devops.domain.manager.influxdb.bean.InfluxDbNode;
import com.vanke.devops.domain.manager.ssh.SSHConfig;
import com.vanke.devops.domain.manager.ssh.SSHManager;
import com.vanke.devops.domain.utils.DesUtil;
import net.schmizz.sshj.SSHClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * <p>
 * 节点表  服务实现类
 * </p>
 *
 * @author 陈景阳
 * @since 2018-03-12
 */
@Service
public class EndpointsServiceImpl extends BaseServiceImpl<EndpointsMapper, Endpoints> implements IEndpointsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(EndpointsServiceImpl.class);

    @Autowired
    private AliyunMonitorManager aliyunMonitorService;

    @Autowired
    private InfluxDbManager influxDbManager;

    @Autowired
    private SSHManager sshManager;

    @Override
    public EndpointsDTO getInfo(Integer id) {
        Endpoints entity = super.queryById(id);

        if(entity == null){
            throw EndpointsErrorCode.NOT_FOUND_ENDPOINT.getException();
        }

        return getInfo(entity);
    }

    @Override
    public EndpointsDTO create(Endpoints entity) {
        this.validIp(entity.getIp());
        //数据加密
        String username = DesUtil.encrypt(entity.getUsername());
        String password = DesUtil.encrypt(entity.getPassword());
        entity.setUsername(username);
        entity.setPassword(password);
        super.add(entity);
        return getInfo(entity);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class,timeout = 4)
    public EndpointsDTO modify(Endpoints entity) {
        //数据加密
        String username = entity.getUsername();
        String password = entity.getPassword();

        //更主机hostname
        SSHConfig config = new SSHConfig(entity.getIp(),username,password);
        sshManager.updateHostname(entity.getHostname(),config);

        entity.setUsername(DesUtil.encrypt(username));
        entity.setPassword(DesUtil.encrypt(password));
        super.update(entity);
        return getInfo(entity.getId());
    }

    @Override
    public Page<EndpointsDTO> page(Integer pageSize, Integer pageNo) {
        Page<Endpoints> page = super.queryPageByFieldsOrKeyword(pageNo,pageSize,new Endpoints());
        Page<EndpointsDTO> resultPage = new Page<>();
        List<EndpointsDTO> list = CollectionUtils.selectListByCopy(page.getRecords(),EndpointsDTO.class);
        resultPage.setRecords(list);
        resultPage.setTotal(page.getTotal());
        return resultPage;
    }

    @Override
    public EndpointsDTO getNodeInfo(Integer id) {
        EndpointsDTO endpoints = getInfo(id);
        InfluxDbNode influxDbNode = influxDbManager.queryNode(endpoints.getTelegrafHostname());
        endpoints.setCpuUsage(new BigDecimal(influxDbNode.getCpu()).setScale(2,BigDecimal.ROUND_HALF_UP));
        endpoints.setMemUsage(new BigDecimal(influxDbNode.getMem()).setScale(2,BigDecimal.ROUND_HALF_UP));
        endpoints.setDiskUsage(new BigDecimal(influxDbNode.getDisk()).setScale(2,BigDecimal.ROUND_HALF_UP));
        return endpoints;
    }


    @Override
    public Node getNodeInfo(String instanceId) {
        return aliyunMonitorService.getNodeInfo(instanceId);
    }

    @Override
    public List<Endpoints> getAll() {
        List<Endpoints> list = baseMapper.selectList(new EntityWrapper<>());
        return CollectionUtils.selectList(list,item -> {
            if(StringUtil.isNotEmpty(item.getIp()) && StringUtil.isNotEmpty(item.getInstanceId())){
                return item;
            }
            return null;
        });
    }

    @Override
    public void delete(Integer id){
        super.delete(id);
    }

    private EndpointsDTO getInfo(Endpoints entity){
        EndpointsDTO dto = new EndpointsDTO();
        dto.setId(entity.getId());
        dto.setInstanceId(entity.getInstanceId());
        dto.setIp(entity.getIp());
        dto.setName(entity.getName());
        dto.setGroup(entity.getGroup());
        dto.setHostname(entity.getHostname());
        dto.setCpu(entity.getCpu());
        dto.setMemory(entity.getMemory());
        dto.setDisk(entity.getDisk());
        dto.setTelegrafHostname(entity.getTelegrafHostname());
        //解密
        String username = DesUtil.decrypt(entity.getUsername());
        String password = DesUtil.decrypt(entity.getPassword());
        dto.setUsername(username);
        dto.setPassword(password);
        return dto;
    }

    private void validIp(String ip){
        if(!ip.startsWith(DomainConstants.IP_PREFIX)){
            throw EndpointsErrorCode.NOT_FOUND_IP.getException();
        }
    }

}